package com.qrpay;

import com.qrpay.model.provider.AbstractRequest;
import com.qrpay.model.provider.AbstractResponse;
import com.qrpay.util.CryptoUtils;
import com.qrpay.util.JsonUtils;
import com.qrpay.util.SendService;
import com.qrpay.util.impl.DefaultSendServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class QrPayClient {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 网络传输服务
     */
    private SendService sendService = new DefaultSendServiceImpl();

    private int connectTimeout = 3_000;
    private int socketTimeout = 15_000;

    private String apiVersion = "1.0";

    /**
     * 系统分配给对接电商的AppId
     */
    private String appId;
    /**
     * 系统分配给对接电商的密钥
     */
    private String appSecretKey;

    public QrPayClient(String appId, String appSecretKey) {
        this.appId = appId;
        this.appSecretKey = appSecretKey;
    }

    /**
     * Api交互（自动进行签名加密）
     *
     * @param <REQ    extends AbstractApiRequest<RES>, RES>
     * @return
     * @throws Exception
     */
    public <REQ extends AbstractRequest<RES>, RES extends AbstractResponse>
    RES execute(String url, REQ request) throws Exception {
        request.setAppId(this.appId);

        request.setSign(CryptoUtils.sign(request, appSecretKey));

        sendService.setTimeOut(connectTimeout, socketTimeout);
        String body = JsonUtils.bean2json(request);
        logger.debug("Request：url={}, body={}", url, body);
        body = sendService.sendPost(url, JsonUtils.bean2json(request));
        logger.debug("Response：body={}", body);

        RES response = JsonUtils.json2Bean(body, request.responseClass());
        CryptoUtils.verifySign(response.getSign(), response, appSecretKey);
        return response;
    }

    public QrPayClient setSendService(SendService sendService) {
        this.sendService = sendService;
        return this;
    }

    public QrPayClient setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
        return this;
    }

    public QrPayClient setSocketTimeout(int socketTimeout) {
        this.socketTimeout = socketTimeout;
        return this;
    }

    public QrPayClient setApiVersion(String apiVersion) {
        this.apiVersion = apiVersion;
        return this;
    }

    public QrPayClient setAppId(String appId) {
        this.appId = appId;
        return this;
    }

    public QrPayClient setAppSecretKey(String appSecretKey) {
        this.appSecretKey = appSecretKey;
        return this;
    }
}
